package com.yulp.springboot2task.service;

import com.yulp.springboot2task.config.SimpleQuartzManager2;
import com.yulp.springboot2task.job.NotifyScheduler;
import com.yulp.springboot2task.job.SimpleQuartzJob;
import com.yulp.springboot2task.test.TestAction;
import com.yulp.springboot2task.utils.DateUtil;
import net.greghaines.jesque.Config;
import net.greghaines.jesque.Job;
import net.greghaines.jesque.client.Client;
import net.greghaines.jesque.worker.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

import static net.greghaines.jesque.utils.JesqueUtils.entry;
import static net.greghaines.jesque.utils.JesqueUtils.map;

/**
 * @description:
 * @date: 2019/11/4 16:37.
 * @author: yulipeng.
 */
@Service
public class TestServiceImpl {

    @Autowired
    @Qualifier("threadPool")
    private ThreadPoolTaskExecutor executor;

    //@Autowired
    //@Qualifier("jesqueClient")
    private Client client;

    //@Autowired
    //@Qualifier("jesqueConfig")
    private Config config;

    @Autowired
    private NotifyScheduler scheduler;


    public static String JOB_NAME = "动态任务调度8"; //不能重复

    public static String TRIGGER_NAME = "动态任务触发器8"; //不能重复

    public static String JOB_GROUP_NAME = "XLXXCC_JOB_GROUP";

    public static String TRIGGER_GROUP_NAME = "XLXXCC_JOB_GROUP";

    //@Autowired
    //private SimpleQuartzManager SimpleQuartzManager;

    /**
     * quartz 方式二: 推荐
     */
    public void quartz4(){
        try {
            Map map = new HashMap();
            map.put("jobType", DateUtil.currentDateLong());
            System.out.println(DateUtil.currentDateLong()+ ":【系统启动】开始(两秒后执行，每3秒输出一次)...");
            SimpleQuartzManager2.addJob(JOB_NAME, JOB_GROUP_NAME, TRIGGER_NAME, TRIGGER_GROUP_NAME,
                    SimpleQuartzJob.class, 2L, 3, 9, map);

            Thread.sleep(20000);
            System.out.println(DateUtil.currentDateLong()+ "【移除定时】开始...");
            SimpleQuartzManager2.removeJob(JOB_NAME, JOB_GROUP_NAME, TRIGGER_NAME, TRIGGER_GROUP_NAME);
            System.out.println("【移除定时】成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * quartz 方式二: 推荐
     */
    public void quartz3(){
        try {
            System.out.println(DateUtil.currentDateLong()+ "【系统启动】开始(每1秒输出一次)...");
            SimpleQuartzManager2.addJob(JOB_NAME, JOB_GROUP_NAME, TRIGGER_NAME, TRIGGER_GROUP_NAME,
                    SimpleQuartzJob.class, 2L, "0/1 * * * * ?", null);

            Thread.sleep(3000);
            System.out.println(DateUtil.currentDateLong()+ "【修改时间】开始(每3秒输出一次)...");
            SimpleQuartzManager2.modifyJobTime(TRIGGER_NAME, TRIGGER_GROUP_NAME, "0/3 * * * * ?");

            Thread.sleep(30000);
            System.out.println(DateUtil.currentDateLong()+ "【移除定时】开始...");
            SimpleQuartzManager2.removeJob(JOB_NAME, JOB_GROUP_NAME, TRIGGER_NAME, TRIGGER_GROUP_NAME);
            System.out.println("【移除定时】成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * quartz 方式一
     * @param orderNo
     * @param jobType
     */
    public void quartzJobTest(String orderNo, String jobType){
        //规则：5秒后执行(1+10=11)次，间隔3秒
        scheduler.sendNotify(1000 * 5L, 3, 10,
                orderNo, jobType);
    }

    public void test2() {
        executor.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("111");
            }
        });
    }

    public Job createJob() {
        /*final Job job = new Job("TestAction",
                new Object[]{1, 2.3, true, "test", Arrays.asList("inner", 4.5)});
        return job;*/
        return null;
    }

    /**
     *
     * @param job
     * @param queueName 队列名
     * @param future job执行时间点，格式：时间戳，单位：秒
     * @param frequency 以后每隔多长时间执行一次, 单位：秒
     * @return
     */
    public Worker executeJob(String queueName, final Job job, final long future, final long frequency, Class<?> zlass) {
        //任务类型3：任务类型创建循环定时任务: 10秒后执行job，以后每隔1分钟执行一次
        client.recurringEnqueue(queueName, job, System.currentTimeMillis() + (future * 1000), (frequency * 1000));

        // 启动监听者
        return worker(queueName, zlass.getName(), zlass);
    }

    /**
     * 循环定时任务类型--取消任务
     * @param queue
     * @param job
     */
    public void removeRecurringEnqueue(String queue, final Job job, Worker worker){
        System.out.println("====取消任务-=====");
        //取消定时任务
        client.removeRecurringEnqueue(queue, job);
        // 退出到Redis服务器的连接
        client.end();

        worker.end(true);
    }

    public Worker worker(String queueName, String className, Class<?> zlass){
        // 启动一个worker从队列运行作业
        /*final MyWorkerImpl worker = new MyWorkerImpl(config,
                Arrays.asList(queueName), new MapBasedJobFactory(map(entry(className, zlass))), queueName);
        Future<String> future = executor.submit(worker);
        if(!future.isDone()){
            System.out.println("task has not finished, please wait!");
        }
        try {
            System.out.println("yyyyyyyyyyyyyyy: "+future.get());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            executor.shutdown();
            worker.worker.end(true);
        }*/

        final Worker worker = new WorkerImpl(config,
                Arrays.asList(queueName), new MapBasedJobFactory(map(entry(className, zlass))));
        executor.execute(worker);
        /*boolean isRun = true;
        while(isRun) {
            if (worker.isProcessingJob()) {
                //worker.end(true);
                isRun = false;
                System.out.println("zzzzzzz122233333zzzzzz");
            }
        }*/
        System.out.println("zzzzzzzzzzzzz");


        // Listeners: 可以在特定Worker事件期间执行自定义回调。
        int myVar = 0;
        worker.getWorkerEventEmitter().addListener(new WorkerListener(){
            @Override
            public void onEvent(WorkerEvent event, Worker worker, String queue, Job job,
                                Object runner, Object result, Throwable t) {
                if (runner instanceof TestAction) {
                    ((TestAction) runner).setSomeVariable(myVar);
                }
            }
        }, WorkerEvent.JOB_SUCCESS);

        /**
         * 可用的工人事件
         * WORKER_START 已完成启动，即将开始运行。
         * WORKER_POLL 轮询队列。
         * JOB_PROCESS 处理作业。
         * JOB_EXECUTE 即将执行物化作业。
         * JOB_SUCCESS 成功执行了物化作业。
         * JOB_FAILURE 在执行物化作业期间捕获到异常。
         * WORKER_ERROR 在正常操作期间捕获到异常。
         * WORKER_STOP 已完成运行，即将关闭。
         */

        return worker;
    }
}
